﻿SmitearWebGL.Core.Structure.Map = Class.extend(
{
	/******** constructor ********/
	
	init : function()
	{
		this._registClass( "SmitearWebGL.Core.Structure.Map" );
		
		/******** public property ********/
		
		this.iterator = new SmitearWebGL.Core.Structure.Map.Iterator( this );
		
		/******** private property ********/
		
		this._compareMode = 1;
		this._size = 0;
		this._arrKeys = [];
		this._arrValues = [];
	}
	,
	
	/******** public method ********/
	
	size : function()
	{
		return this._size;
	}
	,
	item : function( key )
	{
		var idx = this.getElementIndexInArray( this._arrKeys, key );

		if( idx != - 1 )
		return this._arrValues[idx];
		else
		return null;
	}
	,
	keys : function()
	{
		return this._arrKeys;
	}
	,
	values : function()
	{
		return this._arrValues;
	}
	,
	add : function( key, value )
	{
		if( this.checkKey( key ) && this.checkValue( value ) )
		{
			this._arrKeys[this._size] = key;
			this._arrValues[this._size] = value;
			this._size ++ ;
		}
		else
		{
			$THROW( false, "在将键和值添加到字典时发生错误，可能是键无效或者键已经存在");
		}
	}
	,
	batchAdd : function( keys, values )
	{
		var bSuccessed = false;
		if( keys != null && keys != undefined && values != null && values != undefined )
		{
			if( keys.length == values.length && keys.length > 0 )
			{
				var allKeys = this._arrKeys.concat( keys );
				if( ! isArrayElementRepeat( allKeys ) )
				{
					this._arrKeys = allKeys;
					this._arrValues = this._arrValues.concat( values );
					this._size = this._arrKeys.length;
					bSuccessed = true;
				}
			}
		}
		return bSuccessed;
	}
	,
	clear : function()
	{
		if( this._size != 0 )
		{
			this._arrKeys.splice( 0, this._size );
			this._arrValues.splice( 0, this._size );
			this._size = 0;
		}
	}
	,
	containsValue : function( value )
	{
		return this.getElementIndexInArray( this._arrValues, value ) != - 1;
	}
	,
	remove : function( key )
	{
		var idx = this.getElementIndexInArray( this._arrKeys, key );
		var value = null;
		
		if( idx != - 1 )
		{
			value = this._arrValues[idx];
			this._arrKeys.splice( idx, 1 );
			this._arrValues.splice( idx, 1 );
			this._size -- ;
		}
		
		return value;
	}
	,
	tryGetValue : function( key, defaultValue )
	{
		var idx = this.getElementIndexInArray( this._arrKeys, key );
		if( idx != - 1 )
		{
			return this._arrValues[idx];
		}
		else
		return defaultValue;
	}
	,
	toString : function()
	{
		if( this._size == 0 )
		return "";
		else
		return this._arrKeys.toString() + ";" + this._arrValues.toString();
	}
	,
	checkKey : function( key )
	{
		if( key == null || key == undefined || key == "" || key == NaN )
		return false;
		return (this.getElementIndexInArray( this._arrKeys, key ) == - 1);
	}
	,
	checkValue : function( value )
	{
		if ( value == undefined || value == null || value == NaN )
		return false;
		return true;
	}
	,
	getElementIndexInArray : function( arr, e )
	{
		var idx = - 1;
		var i;
		if( ! ( arr == null || arr == undefined || typeof( arr ) != "object" ) )
		{
			for( i = 0; i < arr.length; i ++ )
			{
				var bEqual;
				if( this._compareMode == 0 )
				bEqual = ( arr[i] === e );
				else
				bEqual = ( arr[i] == e );
				if( bEqual )
				{
					idx = i;
					break;
				}
			}
		}
		return idx;
	}
	,
	isArrayElementRepeat : function( arr )
	{
		var bRepeat = false;
		if( arr != null && arr != undefined && typeof( arr ) == "object" )
		{
			var i;
			for( i = 0; i < arr.length - 1; i ++ )
			{
				var bEqual;
				if( this._compareMode == 0 )
				bEqual = ( arr[i] === arr[i + 1] );
				else
				bEqual = ( arr[i] == arr[i + 1] );
				if( bEqual )
				{
					bRepeat = true;
					break;
				}
			}
		}
		return bRepeat;
	}
}
);

SmitearWebGL.Core.Structure.Map.Iterator = Class.extend(
{
	/******** constructor ********/
	
	init : function( map )
	{
		this._registClass( "SmitearWebGL.Core.Structure.Map.Iterator" );
		
		this._map = map;
		this.begin();
	}
	,
	
	/******** public method ********/
	
	hasNext : function()
	{
		return ( this._cousor < this._map.size - 1 );
	}
	,
	next : function()
	{
		++ this._cousor;
	}
	,
	begin : function()
	{
		this._cousor = 0;
	}
	,
	end : function()
	{
		return this._cousor < this._map._size;
	}
	,
	item : function()
	{
		return { key:this._map._arrKeys[this._cousor], value:this._map._arrValues[this._cousor] };
	}
}
);